package com.github.tomakehurst.wiremock.admin.tasks;

import com.github.tomakehurst.wiremock.admin.AdminTask;
import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder;
import com.github.tomakehurst.wiremock.common.Json;
import com.github.tomakehurst.wiremock.common.url.PathParams;
import com.github.tomakehurst.wiremock.core.Admin;
import com.github.tomakehurst.wiremock.extension.export.StubExportHelper;
import com.github.tomakehurst.wiremock.http.ResponseDefinition;
import com.github.tomakehurst.wiremock.stubbing.ServeEvent;
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
import com.github.tomakehurst.wiremock.verification.LoggedRequest;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * 兼容版批量导出任务：无 RequestSpec 依赖，手动读取请求体
 * 对应接口：POST /__admin/mappings/export/batch
 */
public class ExportBatchStubsTask implements AdminTask {

    // 内部请求体模型：与前端 JSON 对应（WireMock 2.x Json 可解析）
    private static class BatchExportReq {
        private List<String> stubIds;

        // 必须提供 Getter/Setter（Json 解析依赖）
        public List<String> getStubIds() {
            return stubIds;
        }

        public void setStubIds(List<String> stubIds) {
            this.stubIds = stubIds;
        }
    }

    @Override
    public ResponseDefinition execute(Admin admin, ServeEvent serveEvent, PathParams pathParams) {
        try {
            // 1. 手动读取请求体（替代 RequestSpec.getBodyAsString()）
            if (serveEvent == null || serveEvent.getRequest() == null){
                return ResponseDefinitionBuilder.responseDefinition()
                        .withStatus(400)
                        .withBody("Stub ID list cannot be empty")
                        .build();
            }
            LoggedRequest request = serveEvent.getRequest();
            String reqBody = request.getBodyAsString();
            if (reqBody == null || reqBody.trim().isEmpty()) {
                return ResponseDefinitionBuilder.responseDefinition()
                        .withStatus(400)
                        .withBody("Request body cannot be empty. Need: {\"stubIds\": [\"id1\", \"id2\"]}")
                        .build();
            }

            // 2. 原生 Json 解析请求体（2.x 及以上通用）
            BatchExportReq batchReq = Json.read(reqBody, BatchExportReq.class);
            if (batchReq.getStubIds() == null || batchReq.getStubIds().isEmpty()) {
                return ResponseDefinitionBuilder.responseDefinition()
                        .withStatus(400)
                        .withBody("Stub ID list cannot be empty")
                        .build();
            }

            // 3. 批量获取 Stub（原生 Admin API）
            List<StubMapping> stubs = new ArrayList<>();
            for (String idStr : batchReq.getStubIds()) {
                UUID stubId = UUID.fromString(idStr);
                StubMapping stub = admin.getStubMapping(stubId).getItem();
                if (stub != null) {
                    stubs.add(stub);
                }
            }

            if (stubs.isEmpty()) {
                return ResponseDefinitionBuilder.responseDefinition()
                        .withStatus(404)
                        .withBody("No valid stubs found")
                        .build();
            }

            // 4. 构建 ZIP 下载响应
            byte[] zipBytes = StubExportHelper.exportBatch(stubs);
            return ResponseDefinitionBuilder.responseDefinition()
                    .withStatus(200)
                    .withHeader("Content-Disposition", "attachment; filename=\"" + StubExportHelper.getBatchFileName() + "\"")
                    .withHeader("Content-Type", "application/zip")
                    .withHeader("Content-Length", String.valueOf(zipBytes.length))
                    .withBody(zipBytes)
                    .build();

        } catch (IllegalArgumentException e) {
            // 处理 UUID 格式错误
            return ResponseDefinitionBuilder.responseDefinition()
                    .withStatus(400)
                    .withBody("Invalid Stub ID: " + e.getMessage())
                    .build();
        } catch (Exception e) {
            // 处理 JSON 解析、ZIP 生成失败
            return ResponseDefinitionBuilder.responseDefinition()
                    .withStatus(500)
                    .withBody("Batch export failed: " + e.getMessage())
                    .build();
        }
    }
}